#region Header Licence
//  NKnobMan, Copyright 2009, Alexandre MUTEL.
// 
//  This is free software; you can redistribute it and/or modify it
//  under the terms of the GNU Lesser General Public License as
//  published by the Free Software Foundation; either version 2.1 of
//  the License, or (at your option) any later version.
// 
//  This software is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//  Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public
//  License along with this software; if not, write to the Free
//  Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
//  02110-1301 USA, or see the FSF site: http://www.fsf.org.
#endregion
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization;

namespace NKnobMan.Templatizer
{
    /// <summary>
    /// TemplateIteration class.
    /// </summary>
    [DataContract]
    public class TemplateIteration
    {
        private Bitmap _generatedBitmap;
        private Size _knobSize;

        public TemplateIteration()
        {
            Name = "Default";
            Operations = new BindingList<TemplateOperation>();
        }

        public TemplateIteration(string name, IterationInput parent, PreviewMouseEvent preview)
        {
            Name = name;
            Input = parent;
            Preview = preview;
            Operations = new BindingList<TemplateOperation>();
        }

        public void LoadBitmap(string filename, Size knobSize)
        {
            if (File.Exists(filename))
            {
                FileStream bitmapStream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
                using (Bitmap bitmap = new Bitmap(bitmapStream))
                {
                    _generatedBitmap = new Bitmap(bitmap);
                }
                bitmapStream.Close();

                _knobSize = knobSize;
            }
        }

        public int Draw(Graphics graphics, Point centerLocation, double ratio)
        {

            int imageNumber = 0;
            if ( _generatedBitmap != null )
            {
                Point leftTop = new Point(centerLocation.X - _knobSize.Width / 2,
                                          centerLocation.Y - _knobSize.Height / 2);

                Rectangle bounds = new Rectangle(leftTop, _knobSize);

                Rectangle sourceRect = new Rectangle(0, 0, _knobSize.Width, _knobSize.Height);
                Point nb = new Point(_generatedBitmap.Width/_knobSize.Width,
                                     _generatedBitmap.Height/_knobSize.Height);

                OutputAlignement outputAlignement = OutputAlignement.Both;

                if (nb.X > nb.Y && nb.Y == 1)
                {
                    outputAlignement = OutputAlignement.Horizontal;
                }
                else if (nb.X < nb.Y && nb.X == 1)
                {
                    outputAlignement = OutputAlignement.Vertical;
                }

                switch (outputAlignement)
                {
                    case OutputAlignement.Both:
                        imageNumber = (int) (ratio*(nb.X *nb.Y-1));
                        int imageNumberX = imageNumber%nb.X;
                        int imageNumberY = imageNumber/nb.X;
                        sourceRect.X = imageNumberX * _knobSize.Width;
                        sourceRect.Y = imageNumberY * _knobSize.Height;
                        break;
                    case OutputAlignement.Horizontal:
                        imageNumber = (int)(ratio * (nb.X-1));
                        sourceRect.X = imageNumber * _knobSize.Width;
                        break;
                    case OutputAlignement.Vertical:
                        imageNumber = (int)(ratio * (nb.Y-1));
                        sourceRect.Y = imageNumber * _knobSize.Height;
                        break;
                }

                graphics.DrawImage(_generatedBitmap, bounds, sourceRect, GraphicsUnit.Pixel);
            }
            return imageNumber;
        }

        public Bitmap GeneratedBitmap
        {
            get { return _generatedBitmap; }
        }

        /// <summary>
        /// Gets or sets the name of this iteration
        /// </summary>
        /// <value>The name.</value>
        [DataMember]
        public string Name { get; set; }

        /// <summary>
        /// Gets or sets the input.
        /// </summary>
        /// <value>The input.</value>
        [DataMember]
        public IterationInput Input { get; set; }

        /// <summary>
        /// Gets or sets the preview.
        /// </summary>
        /// <value>The preview.</value>
        [DataMember]
        public PreviewMouseEvent Preview { get; set; }

        /// <summary>
        /// Gets the operations.
        /// </summary>
        /// <value>The operations.</value>
        [DataMember]
        public BindingList<TemplateOperation> Operations { get; private set; }
    }

    /// <summary>
    /// PreviewMouseEvent enum to specify how to see this iteration in the preview
    /// </summary>
    [DataContract]
    public enum PreviewMouseEvent
    {
        /// <summary>
        /// 
        /// </summary>
        [EnumMember]
        Normal,
        /// <summary>
        /// 
        /// </summary>
        [EnumMember]
        MouseHover,
        /// <summary>
        /// 
        /// </summary>
        [EnumMember]
        MouseClick,
        /// <summary>
        /// 
        /// </summary>
        [EnumMember]
        Disable,
    }

    [DataContract]
    public enum IterationInput
    {
        [EnumMember]
        Original,
        [EnumMember]
        Previous,
    }
}